package patterns.structural.decorator;

/**
 * 装饰器模式示例
 * 动态地给一个对象添加一些额外的职责，就增加功能来说，装饰器模式比生成子类更为灵活
 */
public class DecoratorPattern {

    public static void main(String[] args) {
        // 创建一个简单的咖啡对象
        Beverage simpleCoffee = new SimpleCoffee();
        System.out.println(simpleCoffee.getDescription() + " 价格: ¥" + simpleCoffee.cost());
        
        // 使用装饰器添加调料
        Beverage milkCoffee = new MilkDecorator(simpleCoffee);
        System.out.println(milkCoffee.getDescription() + " 价格: ¥" + milkCoffee.cost());
        
        Beverage sugarMilkCoffee = new SugarDecorator(milkCoffee);
        System.out.println(sugarMilkCoffee.getDescription() + " 价格: ¥" + sugarMilkCoffee.cost());
        
        // 可以直接嵌套多个装饰器
        Beverage specialCoffee = new WhippedCreamDecorator(
                                    new ChocolateDecorator(
                                        new MilkDecorator(
                                            new SimpleCoffee())));
        System.out.println(specialCoffee.getDescription() + " 价格: ¥" + specialCoffee.cost());
        
        // 实际应用示例：Java I/O流
        System.out.println("\n===== Java I/O流装饰器示例 =====");
        DataSource fileDataSource = new FileDataSource("data.txt");
        System.out.println("原始数据: " + fileDataSource.read());
        
        DataSource encryptedData = new EncryptionDecorator(fileDataSource);
        System.out.println("加密后: " + encryptedData.read());
        
        DataSource compressedEncryptedData = new CompressionDecorator(encryptedData);
        System.out.println("压缩加密后: " + compressedEncryptedData.read());
        
        // 写入数据
        compressedEncryptedData.write("新数据"); // 会经过压缩和加密
    }
}

/**
 * 咖啡示例
 */
// 组件接口
interface Beverage {
    String getDescription();
    double cost();
}

// 具体组件
class SimpleCoffee implements Beverage {
    @Override
    public String getDescription() {
        return "简单咖啡";
    }
    
    @Override
    public double cost() {
        return 10.0;
    }
}

// 装饰器抽象类
abstract class BeverageDecorator implements Beverage {
    protected Beverage beverage;
    
    public BeverageDecorator(Beverage beverage) {
        this.beverage = beverage;
    }
    
    @Override
    public String getDescription() {
        return beverage.getDescription();
    }
    
    @Override
    public double cost() {
        return beverage.cost();
    }
}

// 具体装饰器：牛奶
class MilkDecorator extends BeverageDecorator {
    public MilkDecorator(Beverage beverage) {
        super(beverage);
    }
    
    @Override
    public String getDescription() {
        return beverage.getDescription() + ", 加牛奶";
    }
    
    @Override
    public double cost() {
        return beverage.cost() + 2.0;
    }
}

// 具体装饰器：糖
class SugarDecorator extends BeverageDecorator {
    public SugarDecorator(Beverage beverage) {
        super(beverage);
    }
    
    @Override
    public String getDescription() {
        return beverage.getDescription() + ", 加糖";
    }
    
    @Override
    public double cost() {
        return beverage.cost() + 1.0;
    }
}

// 具体装饰器：巧克力
class ChocolateDecorator extends BeverageDecorator {
    public ChocolateDecorator(Beverage beverage) {
        super(beverage);
    }
    
    @Override
    public String getDescription() {
        return beverage.getDescription() + ", 加巧克力";
    }
    
    @Override
    public double cost() {
        return beverage.cost() + 3.0;
    }
}

// 具体装饰器：奶油
class WhippedCreamDecorator extends BeverageDecorator {
    public WhippedCreamDecorator(Beverage beverage) {
        super(beverage);
    }
    
    @Override
    public String getDescription() {
        return beverage.getDescription() + ", 加奶油";
    }
    
    @Override
    public double cost() {
        return beverage.cost() + 4.0;
    }
}

/**
 * I/O流示例
 */
// 组件接口
interface DataSource {
    String read();
    void write(String data);
}

// 具体组件
class FileDataSource implements DataSource {
    private String filename;
    private String data = "原始文件数据";
    
    public FileDataSource(String filename) {
        this.filename = filename;
    }
    
    @Override
    public String read() {
        return data;
    }
    
    @Override
    public void write(String data) {
        System.out.println("写入文件 " + filename + ": " + data);
        this.data = data;
    }
}

// 装饰器抽象类
abstract class DataSourceDecorator implements DataSource {
    protected DataSource wrappee;
    
    public DataSourceDecorator(DataSource source) {
        this.wrappee = source;
    }
    
    @Override
    public String read() {
        return wrappee.read();
    }
    
    @Override
    public void write(String data) {
        wrappee.write(data);
    }
}

// 具体装饰器：加密
class EncryptionDecorator extends DataSourceDecorator {
    public EncryptionDecorator(DataSource source) {
        super(source);
    }
    
    @Override
    public String read() {
        return decrypt(wrappee.read());
    }
    
    @Override
    public void write(String data) {
        wrappee.write(encrypt(data));
    }
    
    private String encrypt(String data) {
        // 简单的加密示例，实际应用中会使用真正的加密算法
        return "加密(" + data + ")";
    }
    
    private String decrypt(String data) {
        // 简单的解密示例
        if (data.startsWith("加密(") && data.endsWith(")")) {
            return data.substring(3, data.length() - 1);
        }
        return data;
    }
}

// 具体装饰器：压缩
class CompressionDecorator extends DataSourceDecorator {
    public CompressionDecorator(DataSource source) {
        super(source);
    }
    
    @Override
    public String read() {
        return decompress(wrappee.read());
    }
    
    @Override
    public void write(String data) {
        wrappee.write(compress(data));
    }
    
    private String compress(String data) {
        // 简单的压缩示例
        return "压缩(" + data + ")";
    }
    
    private String decompress(String data) {
        // 简单的解压示例
        if (data.startsWith("压缩(") && data.endsWith(")")) {
            return data.substring(3, data.length() - 1);
        }
        return data;
    }
} 